#include <iostream>
#include <cstring>
#include <sys/ipc.h> //Inter-Process Communication
#include <sys/shm.h>
#include <unistd.h>
#include "comm.hpp"

int main()
{
    key_t key = GetKey();
    std::cout << "key : " << ToHex(key) << std::endl;
    sleep(3);
    // key vs shmid
    // shmid: 应用这个共享内存的时候，我们使用shmid来进行操作共享内存， FILE*
    // key: 不要在应用层使用，只用来在内核中标识shm的唯一性！， fd
    int shmid = CreateShm(key);

    sleep(5);

    std::cout << "shmid: " << shmid << std::endl;
    std::cout << "开始将shm映射到进程的地址空间中" << std::endl;
    char *s = (char*)shmat(shmid, nullptr, 0);//at就是attach（挂接），第二个参数nullptr就是让操作系统帮我们选择合适的共享空间去挂接
    //（因为不清楚实际的地址），这个函数的返回值类似于malloc，返回挂接到的空间的起始地址，nattach会加1
    sleep(5);
    shmdt(s);//detach（去关联）：本质是修改页表，只需要知道共享内存在进程地址空间的起始地址（虚拟地址），又因为共享内存的大小已知
    //就可以从起始地址处连续释放等于共享内存大小的字节数的空间，这样就修改了映射关系，nattach会减一

    std::cout << "开始将shm从进程的地址空间中移除" << std::endl;

    sleep(5);
    shmctl(shmid, IPC_RMID, nullptr);//删除共享内存，第二参数可以理解为remove immediately，第三个参数可以查看共享内存的属性并且修改
    //如果不需要的话可以设置为空指针
    std::cout << "开始将shm从OS中删除" << std::endl;

    sleep(10);
    return 0;
}
